function [train_data, test_data] = holdoutSplit(data, ratio)
    % 随机打乱数据和标签的顺序
    indices = randperm(size(data, 1));
    shuffled_data = data(indices, :);

    % 获取所有不同的标签
    unique_labels = unique(shuffled_data(:, 1));

    train_data = [];
    test_data = [];

    for i = 1:length(unique_labels)
        label = unique_labels(i);
        
        % 找到当前标签对应的数据索引
        label_indices = find(shuffled_data(:, 1) == label);
        label_data = shuffled_data(label_indices, :);
        
        % 计算划分的边界索引
        split_index = round(ratio * length(label_indices));
        
        % 划分每个类别的数据集
        label_train_data = label_data(1:split_index, :);
        label_test_data = label_data(split_index+1:end, :);
        
        % 将划分后的数据加入总体训练集和测试集
        train_data = [train_data; label_train_data];
        test_data = [test_data; label_test_data];
    end
    
    % 再次打乱train_data和test_data
    train_indices = randperm(size(train_data, 1));
    train_data = train_data(train_indices, :);
    
    test_indices = randperm(size(test_data, 1));
    test_data = test_data(test_indices, :);
end
